/**
 * 这是战网 API 原始数据录入处理动态路由
 */
const Router = require('@koa/router');
const { genResponse } = require('../utils');
const {
  ProfessionsIndex,
  PlayableClassIndex,
  PlayableClass,
  PlayableClassMedia,
  PlayableRaceIndex,
  PlayableRace,
  PlayableSpecIndex,
  PlayableSpec,
  PlayableSpecMedia,
  PowerTypeIndex,
  PowerType,
  MythicKeystoneAffixesIndex,
  MythicKeyStoneAffix,
  MythicKeyStoneAffixMedia,
  Spell,
  SpellMedia,
  JournalInstance,
  JournalInstanceMedia,
  JournalEncounter,
  Item,
  ItemMedia,
  MythicKeystoneDungeonsIndex,
  MythicKeystoneDungeon,
  ToyIndex,
  Toy,
} = require('../db/schemas');

const router = new Router({ prefix: '/game-data' })

/**
 * 对应前端原始数据录入接口
 * 新增的时候，前后端同时添加
 * */
const modelMap = {
  "professions-index": ProfessionsIndex,
  'playable-class-index': PlayableClassIndex,
  'playable-class': PlayableClass,
  'playable-class-media': PlayableClassMedia,
  'playable-race-index': PlayableRaceIndex,
  'playable-race': PlayableRace,
  'playable-spec-index': PlayableSpecIndex,
  'playable-spec': PlayableSpec,
  'playable-spec-media': PlayableSpecMedia,
  'power-type-index': PowerTypeIndex,
  'power-race': PowerType,
  'mythic-keystone-affixes-index': MythicKeystoneAffixesIndex,
  'mythic-keystone-affix': MythicKeyStoneAffix,
  'mythic-keystone-affix-media': MythicKeyStoneAffixMedia,
  'spell': Spell,
  'spell-media': SpellMedia,
  'mythic-keystone-dungeons-index': MythicKeystoneDungeonsIndex,
  'mythic-keystone-dungeon': MythicKeystoneDungeon,
  'journal-instance': JournalInstance,
  'journal-instance-media': JournalInstanceMedia,
  'journal-encounter': JournalEncounter,
  'item': Item,
  'item-media': ItemMedia,
  'toy-index': ToyIndex,
  'toy': Toy,
}

const crudHandler = {
  list(ctx, model) {
    return model.find({}).lean()
  },
  one(ctx, model) {
    return model.findOne({ id: parseInt(ctx.params.id) }).lean()
  },
  async create(ctx, model) {
    const record = await model.findOne({ id: parseInt(ctx.request.body.id) })
    if (record) {
      ctx.throw(400, '记录已存在')
    }
    const doc = new model(ctx.request.body)
    return doc.save()
  },
  update(ctx, model) {
    const id = parseInt(ctx.request.body.id || ctx.params.id)
    return model.findOneAndUpdate({ id }, ctx.request.body)
  },
  delete(ctx, model) {
    return model.findOneAndDelete({ id: parseInt(ctx.params.id) })
  },
}

async function getModel(ctx, next) {
  const { collection } = ctx.params
  const model = modelMap[collection]

  if (!model) {
    ctx.throw(400, `模型映射不存在: ${collection}`)
  }

  // 挂载到 ctx.state 上，方便后续路由直接使用
  ctx.state.model = model

  await next()
}

router.get('/:collection', getModel, async (ctx) => {
  const records = await crudHandler.list(ctx, ctx.state.model)
  ctx.body = genResponse(true, records)
})
router.get('/:collection/:id', getModel, async (ctx) => {
  crudHandler.one(ctx, ctx.state.model)
})
router.post('/:collection/:id?', getModel, async (ctx) => {
  crudHandler.create(ctx, ctx.state.model)
})
router.put('/:collection/:id', getModel, async (ctx) => {
  crudHandler.update(ctx, ctx.state.model)
})
router.delete('/:collection/:id', getModel, async (ctx) => {
  crudHandler.delete(ctx, ctx.state.model)
})
module.exports = router